package sss

type StyleSheet struct {
	Rules     [] Rule
	Palette   [] ColorDef
	Previews  [] Preview
}
type Number = float64
type MaybeNumber = func()(Number,bool)
func SomeNumber(n Number) MaybeNumber {
	return func() (Number, bool) { return n, true }
}

type Rule struct {
	Selector  Selector
	Styles    Styles
	SubRules  [] Rule
}
type Selector interface { Enum(Selector) }
func (ClassSelector) Enum(Selector) {}
type ClassSelector struct {
	Name  string
}
func (PseudoClassSelector) Enum(Selector) {}
type PseudoClassSelector struct {
	Negate  bool
	Name    string
}
type Styles struct {
	Geometry
	FancyBox
	LayoutConfig
	TextConfig
}

type ColorDef struct {
	Name   string
	Value  ColorValue
}
type ColorValue struct {
	Set  bool
	H    Number
	S    Number
	L    Number
	A    MaybeNumber
}
func (def ColorDef) Color() Color {
	return Color { Set: true, Name: def.Name }
}
type Color struct {
	Set   bool
	Name  string
}
func ColorOf(name string, h Number, s Number, l Number, a MaybeNumber) ColorDef {
	return ColorDef {
		Name:  name,
		Value: ColorValue { Set: true, H: h, S: s, L: l, A: a },
	}
}

type Preview struct {
	Name  string
	Root  Box
}
type Box struct {
	ElementKind  string  // div, button, input, ...
	PseudoState  string  // hover, activated, ...
	ClassList    [] string
	Children     [] Box
}

type Geometry struct {
	Position
	Spacing
	Size
	Overflow  MaybeOverflow
}
type Measure struct {
	Set    bool
	Value  Number
	Unit   string
}
func MeasureOf(unit string) func(Number)(Measure) {
	return func(value Number) Measure {
		return Measure { Set: true, Value: value, Unit: unit }
	}
}
type QuadMeasure struct {
	Top     Measure
	Right   Measure
	Bottom  Measure
	Left    Measure
}
func QuadMeasureOf(unit string) func(Number,...Number)(QuadMeasure) {
	{ var unit = MeasureOf(unit)
	return func(first Number, rest ...Number) QuadMeasure {
		var q QuadMeasure
		q.Top = unit(first)
		if 0 < len(rest) { q.Right = unit(rest[0]) }
		if 1 < len(rest) { q.Bottom = unit(rest[1]) }
		if 2 < len(rest) { q.Left = unit(rest[2]) }
		return q
	} }
}
type Position struct {
	Positioning  string
	LayerIndex   MaybeNumber  // z-index
	Top          Measure
	Right        Measure
	Bottom       Measure
	Left         Measure
}
type Spacing struct {
	Margin       QuadMeasure
	Padding      QuadMeasure
	BorderWidth  QuadMeasure
}
type Size struct {
	Width      Measure
	Height     Measure
	MinWidth   Measure
	MinHeight  Measure
	MaxWidth   Measure
	MaxHeight  Measure
}
type MaybeOverflow = func()(Overflow,bool)
type Overflow struct {
	X  string  // default: hidden
	Y  string  // default: hidden
}

type FancyBox struct {
	BorderStyle   BorderStyle
	BorderColor   Color
	BoxShadows    [] BoxShadow
	Background    MaybeBackground
}
type BorderStyle struct {
	BorderKind  string
}
type BoxShadow struct {
	Inset         bool
	OffsetX       Measure
	OffsetY       Measure
	BlurRadius    Measure
	SpreadRadius  Measure
	Color         Color
}
type Background struct {
	Content  BackgroundContent
}
type MaybeBackground = func()(Background,bool)
type BackgroundContent interface { Enum(BackgroundContent) }
func (BackgroundColor) Enum(BackgroundContent) {}
type BackgroundColor struct {
	Color  Color
}
func (BackgroundSimpleGradient) Enum(BackgroundContent) {}
type BackgroundSimpleGradient struct {
	Gradient  SimpleGradient
}
type SimpleGradient struct {
	To     string
	Start  Color
	End    Color
}

type LayoutConfig struct {
	ItemConfig       LayoutItemConfig
	ContainerConfig  MaybeLayoutContainerConfig
}
type LayoutItemConfig struct {
	Order       MaybeNumber
	FlexGrow    MaybeNumber
	FlexShrink  MaybeNumber
	FlexBasis   Measure
	AlignSelf   string
	GridArea    MaybeGridArea
}
type MaybeGridArea = func()(GridArea,bool)
type GridArea struct {
	StartRow     Number
	StartColumn  Number
	EndRow       Number
	EndColumn    Number
}
type MaybeLayoutContainerConfig = func()(LayoutContainerConfig,bool)
type LayoutContainerConfig interface { Enum(LayoutContainerConfig) }
func (BlockContainer) Enum(LayoutContainerConfig) {}
type BlockContainer struct {}
func (InlineContainer) Enum(LayoutContainerConfig) {}
type InlineContainer struct {}
func (InlineBlockContainer) Enum(LayoutContainerConfig) {}
type InlineBlockContainer struct {}
func (FlexContainer) Enum(LayoutContainerConfig) {}
type FlexContainer struct {
	FlexDirection   string
	FlexWrap        string
	JustifyContent  string
	AlignItems      string
	AlignContent    string
	RowGap          Measure
	ColumnGap       Measure
}
func (GridContainer) Enum(LayoutContainerConfig) {}
type GridContainer struct {
	TemplateRows     [] Measure
	TemplateColumns  [] Measure
	RowGap           Measure
	ColumnGap        Measure
}

type TextConfig struct {
	FontConfig      TextFontConfig
	WrapConfig      MaybeTextWrapConfig
	Color           Color
	TextDecoration  string
}
type MaybeTextWrapConfig = func()(TextWrapConfig,bool)
type TextWrapConfig interface { Enum(TextWrapConfig) }
func (SingleLineConfig) Enum(TextWrapConfig) {}
type SingleLineConfig struct {} // text-overflow, white-space
func (MultiLineConfig) Enum(TextWrapConfig) {}
type MultiLineConfig struct { // text-overflow, white-space, overflow-wrap
	HyphensEnabled  bool  // hyphens
}
type TextFontConfig struct {
	FontFamily  [] string
	FontSize    Measure
	FontWeight  string
	FontStyle   string
}


